package com.itc.bpm.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.annotation.Version;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.JsonNode;
import com.itc.bpm.bean.BpmFormDesign;
import com.itc.bpm.dto.FormFiledDto;
import com.itc.bpm.mapper.BpmFormDesignMapper;
import com.itc.bpm.service.BpmFormDesignService;
import com.itc.bpm.util.JsonUtils;
import com.itc.common.core.domain.R;
import com.itc.common.core.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class BpmFormDesignServiceImpl extends ServiceImpl<BpmFormDesignMapper, BpmFormDesign> implements BpmFormDesignService {

    // 排除非展示字段属性
    public static final String UN_FILED_TYPE = "card,form,row,page,col";
    public static final String PREFIX = "form";

    /**
     * 表单修改都是新增版本
     * @param bpmFormDesign
     * @return
     */
    @Autowired(required = false)
    BpmFormDesignMapper bpmFormDesignMapper;
    @Transactional
    @Override
    public R addForm(BpmFormDesign bpmFormDesign) {

        if(bpmFormDesign.getId()==null){ //
            if(StringUtils.isNotEmpty(bpmFormDesign.getFormConf())){
                bpmFormDesign = validBpmFormDesign(bpmFormDesign);
            }
            // 校验名称编码是否重复
            LambdaQueryWrapper<BpmFormDesign> queryWrapper = new LambdaQueryWrapper<BpmFormDesign>().eq(BpmFormDesign::getName,bpmFormDesign.getName()).eq(BpmFormDesign::getDelFlag,0);
            List<BpmFormDesign> list1 =bpmFormDesignMapper.selectList(queryWrapper);
            if(list1!=null && list1.size()>0){
                return R.fail("表单名称不能重复");
            }
            bpmFormDesign.setDelFlag(0);
            bpmFormDesign.setStatus(0);
            bpmFormDesign.setVersion("1.0");
            bpmFormDesign.setCode(generate8UUID());
            bpmFormDesignMapper.insert(bpmFormDesign);
        }else{ //修改新增版本
            BpmFormDesign oldForm =bpmFormDesignMapper.selectById(bpmFormDesign.getId());
            //比较表单内容是否发送变化
            if(oldForm!=null){//
                JSONObject jsonObj1 = new JSONObject(oldForm.getFormConf());
                JSONObject jsonObj2 = new JSONObject(bpmFormDesign.getFormConf());
                if(!jsonObj2.equals(jsonObj1) || oldForm.getStatus()==1){ //json不相同新增版本记录
                    // 标记历史记录数据，新增版本号 新记录
                    bpmFormDesignMapper.updateHistoryForm(oldForm.getCode());
                    if(StringUtils.isNotEmpty(bpmFormDesign.getFormConf())){
                        bpmFormDesign = validBpmFormDesign(bpmFormDesign);
                    }
                    bpmFormDesign.setVersion(getLastVersion(oldForm.getCode()));
                    bpmFormDesign.setId(null);
                    bpmFormDesign.setCreateTime(null);
                    bpmFormDesign.setUpdateTime(null);
                    bpmFormDesign.setStatus(0);
                    bpmFormDesign.setCode(oldForm.getCode());
                    bpmFormDesign.setDelFlag(0);
                    bpmFormDesignMapper.insert(bpmFormDesign);
                }
            }else{
                return R.fail("表单不存在，请刷新后重新操作！");
            }
        }
        return R.ok();
    }

    public BpmFormDesign validBpmFormDesign(BpmFormDesign formDesign){
        JSONObject jsonObject = JsonUtils.jsonToObject(formDesign.getFormConf(),JSONObject.class);
        JSONArray array = (JSONArray) jsonObject.get("schemas");
        JSONObject pageObject = (JSONObject) array.get(0);
        if(pageObject.containsKey("componentProps")){
            JSONObject componentProps = (JSONObject) pageObject.get("componentProps");
            String formName = componentProps.get("name")+"";
            if(componentProps.containsKey("remark")){
                String remark = componentProps.get("remark")+"";
                formDesign.setRemark(remark);
            }
            formDesign.setName(formName);
        }
        JSONArray children = (JSONArray) pageObject.get("children");
        if(children!=null && children.size()>0){
            List<FormFiledDto> list = new ArrayList<>();
            relaxFormScheme(children,list);
            formDesign.setFields(JsonUtils.objectToJson(list));
        }
        return formDesign;
    }

    /**
     * 解析表单获取表单填报字段信息
     * @param nodes
     * @param list
     */
    public static void relaxFormScheme(JSONArray nodes, List<FormFiledDto> list){
        for(int i=0;i<nodes.size();i++){
           JSONObject jsonObject = (JSONObject) nodes.get(i);
           String type = jsonObject.get("type").toString();
           if(!UN_FILED_TYPE.contains(type)){
               FormFiledDto dto = new FormFiledDto();
               String label = jsonObject.get("label").toString();
               String field = jsonObject.get("field").toString();
               dto.setField(field);
               dto.setType(type);
               dto.setLabel(label);
               list.add(dto);
           }else if(jsonObject.containsKey("children")){
               JSONArray children = (JSONArray) jsonObject.get("children");
               if(children!=null && children.size()>0){
                   relaxFormScheme(children,list);
               }
           }
        }

    }

    @Override
    public R deleteForm(String id) {
        String[] ids = id.split(",");
        for(String temId:ids){
            BpmFormDesign bpmFormDesign = new BpmFormDesign();
            bpmFormDesign.setId(Long.parseLong(temId));
            bpmFormDesign.setDelFlag(1);
            bpmFormDesignMapper.updateById(bpmFormDesign);
        }
        return R.ok();
    }

    @Override
    public BpmFormDesign findCurrentForm(String formCode) {
        return this.getOne(new LambdaQueryWrapper<BpmFormDesign>().eq(BpmFormDesign::getCode,formCode).eq(BpmFormDesign::getStatus,0).last("limit 1"));
    }

    public String getLastVersion(String code){
        LambdaQueryWrapper<BpmFormDesign> queryWrapper = new LambdaQueryWrapper<BpmFormDesign>().eq(BpmFormDesign::getCode,code).orderByDesc(BpmFormDesign::getCreateTime).last("limit 1");
        BpmFormDesign bpmFormDesign = bpmFormDesignMapper.selectOne(queryWrapper);
        Integer num = 1;
        if(StringUtils.isNotEmpty(bpmFormDesign.getVersion())){
            float tempVaersion = Float.parseFloat(bpmFormDesign.getVersion());
            num = (int) tempVaersion;
            num++;
        }
        return num+".0";
    }


    public static String generate8UUID() {
        UUID uuid = UUID.randomUUID();
        String str = uuid.toString().replace("-", "");
        return PREFIX+str;
    }

}
